package poli.tidia.mobile.proxy;

     import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;


     public class RestClient {
    	 private HttpClient client;
    	 private static RestClient _instance;
    	 private HttpContext localContext;
    	 
    	 private RestClient() 
    	 {
    		 client = new DefaultHttpClient();
    		 CookieStore cookieStore = new BasicCookieStore();
    		 localContext = new BasicHttpContext();
    		 localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
    	 }
    	 public static RestClient getInstance(String url)
    	 {
    		 if (_instance == null || url.endsWith("xlogin")) {
    			 _instance = new RestClient();
    		 }
    		 _instance.url = url;
             _instance.params = new ArrayList<NameValuePair>();
             _instance.headers = new ArrayList<NameValuePair>();
    		 return _instance;
    	 }
    	 
    	 
    	 public enum RequestMethod {
    		 GET,
    		 POST;
    		}
    	 
         private ArrayList <NameValuePair> params;
         private ArrayList <NameValuePair> headers;

         private String url;

         private int responseCode;
         private String message;

         private String response;

         public String getResponse() {
             return response;
         }

         public String getErrorMessage() {
             return message;
         }

         public int getResponseCode() {
             return responseCode;
         }

         public void AddParam(String name, String value)
         {
             params.add(new BasicNameValuePair(name, value));
         }

         public void AddHeader(String name, String value)
         {
             headers.add(new BasicNameValuePair(name, value));
         }

         public void Execute(RequestMethod method) throws Exception
         {
             switch(method) {
                 case GET:
                 {
                     //add parameters
                     String combinedParams = "";
                     if(!params.isEmpty()){
                         combinedParams += "?";
                         for(NameValuePair p : params)
                         {
                             String paramString = p.getName() + "=" + p.getValue();
                             if(combinedParams.length() > 1)
                             {
                                 combinedParams  +=  "&" + paramString;
                             }
                             else
                             {
                                 combinedParams += paramString;
                             }
                         }
                     }

                     HttpGet request = new HttpGet(url + combinedParams);

                     //add headers
                     for(NameValuePair h : headers)
                     {
                         request.addHeader(h.getName(), h.getValue());
                     }
                     executeRequest(request, url);
                     break;
                 }

                 case POST:
                 {
                     HttpPost request = new HttpPost(url);

                     //add headers
                     for(NameValuePair h : headers)
                     {
                         request.addHeader(h.getName(), h.getValue());
                     }

                     if(!params.isEmpty()){
                         request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
                     }

                     executeRequest(request, url);
                     break;
                 }
             }
         }

         private void executeRequest(HttpUriRequest request, String url)
         {
             

             HttpResponse httpResponse;

             try {
                 httpResponse = client.execute(request, localContext);
                 responseCode = httpResponse.getStatusLine().getStatusCode();
                 message = httpResponse.getStatusLine().getReasonPhrase();
                 
                 HttpEntity entity = httpResponse.getEntity();

                 if (entity != null) {
                     InputStream instream = entity.getContent();
                     response = convertStreamToString(instream);

                     // Closing the input stream will trigger connection release
                     instream.close();
                 }
             }
             catch (ClientProtocolException e)  {
                 client.getConnectionManager().shutdown();
                 e.printStackTrace();
             } catch (IOException e) {
                 client.getConnectionManager().shutdown();
                 e.printStackTrace();
             }
         }

         private static String convertStreamToString(InputStream is) {
             BufferedReader reader = new BufferedReader(new InputStreamReader(is));
             StringBuilder sb = new StringBuilder();

             String line = null;
             try {
                 while ((line = reader.readLine()) != null) {
                     sb.append(line + "\n");
                 }
             }
             catch (IOException e) {
                 e.printStackTrace();
             }
             finally {
                 try {
                     is.close();
                 } catch (IOException e) {
                     e.printStackTrace();
                 }
             }
             return sb.toString();
         }
     }